package com.spring.application;

import com.spring.annotation.*;
import com.spring.exception.NotAnnotationException;
import com.spring.factory.AbstractBeanFactory;
import com.spring.utils.ClassUtil;
import java.util.HashSet;
import java.util.Set;

public class AnnotationApplicationContext implements ApplicationContext {
    private Class<?> clazz;
    private Set<Class<?>> classSet = new HashSet<Class<?>>();
    private AbstractBeanFactory abstractBeanFactory;

    public AnnotationApplicationContext(Class<?> clazz) {
        this.clazz = clazz;
        abstractBeanFactory = AbstractBeanFactory.getAbstractBeanFactory();
        this.refresh();
    }

    void refresh() {
        scan();
        try {
            abstractBeanFactory.beanRegister(classSet);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    public void scan() {
        try {
            Configuration configuration = clazz.getAnnotation(Configuration.class);
            if (configuration == null) {
                throw new NotAnnotationException("");
            }
            CommponentScan scanPackage = clazz.getAnnotation(CommponentScan.class);
            if (scanPackage == null) {
                throw new NotAnnotationException("");
            }
            String[] value = scanPackage.value();
            for (String v : value) {
                Set<Class<?>> classes = ClassUtil.getClasses(v);
                classSet.addAll(classes);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public <T> T getBean(String beanId) {
        return abstractBeanFactory.getBean(beanId);
    }

    public <T> T getBean(String beanId, Class<T> clazz) {
        return abstractBeanFactory.getBean(beanId,clazz);
    }

    public <T> T getBean(Class<T> clazz) {
        return abstractBeanFactory.getBean(clazz);
    }
}
